package org.mx.service.server;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;

import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

/**
 * 描述：TCP/UDP通信部分配置对象
 *
 * @author john peng Date time 2018/7/19 下午4:29
 */
public class CommServerConfigBean {
	@Value("${tcp.enabled:false}")
	private boolean tcpEnabled;
	@Value("${tcp.servers.num:0}")
	private int tcpServerNum;

	@Value("${udp.enabled:false}")
	private boolean udpEnabled;
	@Value("${udp.servers.num:0}")
	private int udpServerNum;

	private Environment env;

	/**
	 * 构造函数
	 * 
	 * @param env Spring环境
	 */
	public CommServerConfigBean(Environment env) {
		super();
		this.env = env;
	}

	/**
	 * 是否开启TCP服务器
	 * 
	 * @return 是否开启TCP服务器
	 */
	public boolean isTcpEnabled() {
		return tcpEnabled;
	}

	/**
	 * 获取TCP服务器数量
	 * 
	 * @return 数量
	 */
	public int getTcpServerNum() {
		return tcpServerNum;
	}

	/**
	 * 是否开启UDP服务器
	 * 
	 * @return 是否开启UDP服务器
	 */
	public boolean isUdpEnabled() {
		return udpEnabled;
	}

	/**
	 * 获取UDP服务器数量
	 * 
	 * @return 数量
	 */
	public int getUdpServerNum() {
		return udpServerNum;
	}

	/**
	 * 创建TCP服务器配置信息
	 * 
	 * @param env    Spring环境
	 * @param prefix 配置前缀
	 * @return 配置信息
	 */
	public TcpServerConfig tcpServerConfig(Environment env, String prefix) {
		TcpServerConfig config = new TcpServerConfig(
				env.getProperty(String.format("%s.port", prefix), Integer.class, 9996),
				env.getProperty(String.format("%s.maxLength", prefix), Integer.class, 1024),
				env.getProperty(String.format("%s.packet.wrapper", prefix)),
				env.getProperty(String.format("%s.receiver", prefix)));
		config.setSoTimeout(env.getProperty(String.format("%s.soTimeout", prefix), Integer.class, 0));
		config.setSendBufferSize(env.getProperty(String.format("%s.sendBufferSize", prefix), Integer.class, 146988));
		config.setReceiveBufferSize(env.getProperty(String.format("%s.recvBufferSize", prefix), Integer.class, 408300));
		config.setReuseAddress(env.getProperty(String.format("%s.reuseAddress", prefix), Boolean.class, true));
		config.setTrafficClass(env.getProperty(String.format("%s.trafficClass", prefix), Integer.class, 0));
		config.setKeepAlive(env.getProperty(String.format("%s.keepAlive", prefix), Boolean.class, false));
		config.setNoDelay(env.getProperty(String.format("%s.noDelay", prefix), Boolean.class, false));
		config.setOobInline(env.getProperty(String.format("%s.oobInline", prefix), Boolean.class, false));
		config.setSoLinger(env.getProperty(String.format("%s.soLinger", prefix), Integer.class, -1));
		return config;
	}

	/**
	 * 获取TCP服务器配置信息列表
	 * 
	 * @return 配置信息列表
	 */
	public List<ServerConfig> getTcpServers() {
		List<ServerConfig> serverConfigs = new ArrayList<>();
		for (int index = 1; index <= tcpServerNum; index++) {
			TcpServerConfig config = tcpServerConfig(env, String.format("tcp.servers.%d", index));
			serverConfigs.add(config);
		}
		return serverConfigs;
	}

	/**
	 * 创建UDP服务器配置信息
	 * 
	 * @param env    Spring环境
	 * @param prefix 配置前缀
	 * @return UDP服务器配置信息
	 */
	public UdpServerConfig udpServerConfig(Environment env, String prefix) {
		UdpServerConfig config = new UdpServerConfig(
				env.getProperty(String.format("%s.port", prefix), Integer.class, 9996),
				env.getProperty(String.format("%s.maxLength", prefix), Integer.class, 1024),
				env.getProperty(String.format("%s.packet.wrapper", prefix)),
				env.getProperty(String.format("%s.receiver", prefix)));
		config.setSoTimeout(env.getProperty(String.format("%s.soTimeout", prefix), Integer.class, 0));
		config.setSendBufferSize(env.getProperty(String.format("%s.sendBufferSize", prefix), Integer.class, 65507));
		config.setReceiveBufferSize(env.getProperty(String.format("%s.recvBufferSize", prefix), Integer.class, 65507));
		config.setReuseAddress(env.getProperty(String.format("%s.reuseAddress", prefix), Boolean.class, false));
		config.setTrafficClass(env.getProperty(String.format("%s.trafficClass", prefix), Integer.class, 0));
		config.setBroadcast(env.getProperty(String.format("%s.broadcast", prefix), Boolean.class, true));
		return config;
	}

	/**
	 * 获取UDP服务器配置信息列表
	 * 
	 * @return 配置信息列表
	 */
	public List<ServerConfig> getUdpServers() {
		List<ServerConfig> serverConfigs = new ArrayList<>();
		for (int index = 1; index <= udpServerNum; index++) {
			UdpServerConfig config = udpServerConfig(env, String.format("udp.servers.%d", index));
			serverConfigs.add(config);
		}
		return serverConfigs;
	}

	/**
	 * 服务器配置信息
	 * 
	 * @author john.peng
	 *
	 */
	@Getter
	@Setter
	public static class ServerConfig {
		private int port, soTimeout, sendBufferSize, receiveBufferSize, trafficClass, maxLength;
		private boolean reuseAddress;
		private String packetWrapper, receiver;

		/**
		 * 默认的构造函数
		 */
		public ServerConfig() {
			super();
		}

		/**
		 * 构造函数
		 * 
		 * @param port          端口号
		 * @param maxLength     最大长度
		 * @param packetWrapper 数据包处理器
		 * @param receiver      接收器
		 */
		public ServerConfig(int port, int maxLength, String packetWrapper, String receiver) {
			super();
			this.port = port;
			this.maxLength = maxLength;
			this.packetWrapper = packetWrapper;
			this.receiver = receiver;
		}
	}

	/**
	 * TCP服务器配置信息
	 * 
	 * @author john.peng
	 *
	 */
	@Getter
	@Setter
	public static class TcpServerConfig extends ServerConfig {
		private boolean keepAlive = false, oobInline = false, noDelay = false;
		private int soLinger = -1;

		/**
		 * 默认的构造函数
		 */
		public TcpServerConfig() {
			this(9996, 1024, null, null);
		}

		/**
		 * 构造函数
		 * 
		 * @param port          端口号
		 * @param maxLength     最大长度
		 * @param packetWrapper 数据包处理器
		 * @param receiver      接收器
		 */
		public TcpServerConfig(int port, int maxLength, String packetWrapper, String receiver) {
			super(port, maxLength, packetWrapper, receiver);
			super.setReceiveBufferSize(408300);
			super.setSendBufferSize(146988);
			super.setReuseAddress(true);
			super.setTrafficClass(0);
			super.setSoTimeout(0);
		}
	}

	/**
	 * UDP服务器配置信息
	 * 
	 * @author john.peng
	 *
	 */
	@Getter
	@Setter
	public static class UdpServerConfig extends ServerConfig {
		private boolean broadcast = true;

		/**
		 * 默认的构造函数
		 */
		public UdpServerConfig() {
			this(9996, 1024, null, null);
		}

		/**
		 * 构造函数
		 * 
		 * @param port          端口号
		 * @param maxLength     最大长度
		 * @param packetWrapper 数据包处理器
		 * @param receiver      接收器
		 */
		public UdpServerConfig(int port, int maxLength, String packetWrapper, String receiver) {
			super(port, maxLength, packetWrapper, receiver);
			super.setReceiveBufferSize(65507);
			super.setSendBufferSize(65507);
			super.setReuseAddress(false);
			super.setTrafficClass(0);
			super.setSoTimeout(0);
		}
	}
}
